﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SpaceMan
{
    enum DrawPasses
    {
        GaussianBlurFirst,
        GaussianBlurSecond,
        TextureAnim

    }
    class FUNC_Shaders
    {
        Effect gaussianBlur, TextureAnim;
        
        Dictionary<DrawPasses, RenderTarget2D> RTDictionary;
        GraphicsDevice gd;
        float start = 0f;
        public FUNC_Shaders(GraphicsDevice gd, Effect gaussianBlur, Effect TextureAnim)
        {
            this.gaussianBlur = gaussianBlur;
            this.gd = gd;
            this.TextureAnim = TextureAnim;
            RTDictionary = new Dictionary<DrawPasses, RenderTarget2D>();
            RTDictionary.Add(DrawPasses.GaussianBlurFirst, new RenderTarget2D(gd, gd.Viewport.Width, gd.Viewport.Height, false, gd.DisplayMode.Format, DepthFormat.Depth24));
            RTDictionary.Add(DrawPasses.GaussianBlurSecond, new RenderTarget2D(gd, gd.Viewport.Width, gd.Viewport.Height, false, gd.DisplayMode.Format, DepthFormat.Depth24));
            RTDictionary.Add(DrawPasses.TextureAnim, new RenderTarget2D(gd, gd.Viewport.Width, gd.Viewport.Height, false, gd.DisplayMode.Format, DepthFormat.Depth24));
            
        }

        public Texture2D GaussianBlur(SpriteBatch spriteBatch, Texture2D RT_2D, Texture2D RT_2DNormal, int GlowSize, float GlowStrength)
        {
            GlowSize = (int)MathHelper.Clamp(GlowSize, 0, 4);
            gaussianBlur.Parameters["Size"].SetValue(GlowSize);
            gaussianBlur.Parameters["TexHeight"].SetValue(gd.Viewport.Height);
            gaussianBlur.Parameters["TexWidth"].SetValue(gd.Viewport.Width);
            gaussianBlur.Parameters["Intensity"].SetValue(GlowStrength);
            //gaussianBlur.Parameters["Tex1"].SetValue(RT_2DNormal);

            float step = (1.0f / (((float)GlowSize * 2.0f) + 1.0f));
            float[] floats = new float[(GlowSize * 2) + 1];


            for (int j = 0; j < floats.Length; j++)
            {
                floats[j] = (1 - Math.Abs((step * j * 2) - 1)) * 0.40f;
            }

            
            gaussianBlur.Parameters["BlurWeights"].SetValue(floats);
            
            
            Vector2[] floats2 = new Vector2[(GlowSize * 2) + 1];

            for (int j = 0; j < floats2.Length; j++)
            {
                floats2[j].X = j - GlowSize;
            }
            gaussianBlur.Parameters["PixelKernel"].SetValue(floats2);
            

            gd.SetRenderTarget(RTDictionary[DrawPasses.GaussianBlurFirst]);
            gd.Clear(Color.Black);

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

            gaussianBlur.CurrentTechnique.Passes[0].Apply();
            spriteBatch.Draw(RT_2D, Vector2.Zero, Color.White);

            spriteBatch.End();

            gd.SetRenderTarget(null);
            RT_2D = (Texture2D)RTDictionary[DrawPasses.GaussianBlurFirst];

            floats2 = new Vector2[(GlowSize * 2) + 1];
            for (int j = 0; j < floats2.Length; j++)
            {
                floats2[j].Y = j - GlowSize;
            }

            gaussianBlur.Parameters["PixelKernel"].SetValue(floats2);

            gd.SetRenderTarget(RTDictionary[DrawPasses.GaussianBlurSecond]);
            gd.Clear(Color.Black);

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            gaussianBlur.CurrentTechnique.Passes[0].Apply();
            spriteBatch.Draw(RT_2D, Vector2.Zero, Color.White);
            spriteBatch.End();

            gd.SetRenderTarget(null);
            return (Texture2D)RTDictionary[DrawPasses.GaussianBlurSecond];

        }

        
        public Texture2D TextureAnimation(SpriteBatch spriteBatch, Texture2D RT_2D, float Increment, float Size)
        {
            float _To = 0f, _SecondStart = 0f, _SecondTo = 0f;
            bool overFlowing = false;
            
            start += Increment;
            _To = start + Size;
            
            if (start > 1)
            {
                 start -= 1;
            }

            if (_To > 1)
            {
                 _To -= 1;
                 overFlowing = true;
            }
            _SecondStart = _To - Size;
            _SecondTo = start + Size;

            
            TextureAnim.Parameters["min"].SetValue(start);
            TextureAnim.Parameters["max"].SetValue(_To);
            TextureAnim.Parameters["underMin"].SetValue(_SecondStart);
            TextureAnim.Parameters["overMax"].SetValue(_SecondTo);

            gd.SetRenderTarget(RTDictionary[DrawPasses.TextureAnim]);
            gd.Clear(Color.Black);


            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            if(!overFlowing)
                TextureAnim.CurrentTechnique.Passes[0].Apply();
            else
                TextureAnim.CurrentTechnique.Passes[1].Apply();
            spriteBatch.Draw(RT_2D, Vector2.Zero, Color.White);
            spriteBatch.End();

            gd.SetRenderTarget(null);
            return (Texture2D)RTDictionary[DrawPasses.TextureAnim];
        }
    }
}
